<?php

namespace exphp;

class RequestNetwork
{

    public static $config = array(
        'Curl' => null,
        'TimeOut' => 30,
        'UserAgent' => false,
        'FollowLocation' => true,
        'AutoReferer' => true,
        'ShowHeader' => false,
    );

    public static $request = array(
        'SSL' => [
            'IsOpen' => false,
            'Cert' => null,
            'Key' => null
        ],
        'Headers' => array(),
        'Url' => '',
        'Prot' => 80,
        'Method' => '',
        'Param' => array(),
        'Body' => array(),
        'BodyType' => 'x-www-form-urlencoded',
        'Cookie' => '',
        'Referer' => ''
    );
    //请求结果
    public static $response = array(
        'Content' => '',
        'Status' => '',
        'Error' => ''
    );

    /** 执行操作 */
    public static function execute()
    {
        //启动一个CURL回话
        self::$config['Curl'] = curl_init();

        //SSL相关信息
        if (self::$request['request']['SSL']['IsOpen']) {
            curl_setopt(self::$config['Curl'], CURLOPT_SSL_VERIFYPEER, true);  //对认证证书来源的检查
            curl_setopt(self::$config['Curl'], CURLOPT_SSL_VERIFYHOST, true);  //从证书中检查SSL加密算法是否存在
            curl_setopt(self::$config['Curl'], CURLOPT_SSLCERT, self::$request['request']['SSL']['SSLCert']);  //设置SSL证书
            curl_setopt(self::$config['Curl'], CURLOPT_SSLCERT, self::$request['request']['SSL']['SSLKEY']);  //设置SSL密钥
        }

        //模拟用户使用的浏览器
        if (self::$config['FollowLocation']) {
            curl_setopt(self::$config['Curl'], CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
        }

        //使用自动跳转
        curl_setopt(self::$config['Curl'], CURLOPT_FOLLOWLOCATION, true);

        //自动设置Referer
        if (self::$config['AutoReferer']) {
            curl_setopt(self::$config['Curl'], CURLOPT_AUTOREFERER, true);
        }

        //设置超时限制防止死循环
        curl_setopt(self::$config['Curl'], CURLOPT_TIMEOUT, self::$config['TimeOut']);

        //获取的信息以文件流的形式返回
        curl_setopt(self::$config['Curl'], CURLOPT_RETURNTRANSFER, true);

        //显示返回的Header区域内容
        if (self::$config['ShowHeader']) {
            curl_setopt(self::$config['Curl'], CURLOPT_HEADER, true);
        }

        //拼接URL
        if (self::$request['Param']) {
            self::$request['Url'] .= '?' . http_build_query(self::$request['Param']);
        }

        //设置请求地址
        curl_setopt(self::$config['Curl'], CURLOPT_URL, self::$request['Url']);

        //设置请求端口
        if (self::$request['Prot'] != 80) {
            curl_setopt(self::$config['Curl'], CURLOPT_PORT, self::$request['Prot']);
        }

        //设置请求方法
        if (self::$request['Method'] == 'GET') {
        } elseif (self::$request['Method'] == 'POST') {
            curl_setopt(self::$config['Curl'], CURLOPT_POST, true);
        } elseif (self::$request['Method'] == 'PUT') {
            curl_setopt(self::$config['Curl'], CURLOPT_CUSTOMREQUEST, 'PUT');
        } elseif (self::$request['Method'] == 'PATCH') {
            curl_setopt(self::$config['Curl'], CURLOPT_CUSTOMREQUEST, 'PATCH');
        } elseif (self::$request['Method'] == 'DELETE') {
            curl_setopt(self::$config['Curl'], CURLOPT_CUSTOMREQUEST, 'DELETE');
        } else {
            OutPut::restfulErrorOutput('not supported request methods', '不支持' . self::$request['Method'] . '请求方法');
        }

        //设置请求体
        if (self::$request['Body']) {
            self::$request['Body'] = http_build_query(self::$request['Body']);
            curl_setopt(self::$config['Curl'], CURLOPT_POSTFIELDS, self::$request['Body']);
            self::setHeaders([
                'Content-Type: application/x-www-form-urlencoded; charset=utf-8',
                'Content-Length:' . strlen(self::$request['Body'])
            ]);
        }

        //设置Headers
        if (self::$request['Cookie']) {
            curl_setopt(self::$config['Curl'], CURLOPT_HTTPHEADER, self::$request['Headers']);
        }

        //设置Cookie
        if (self::$request['Cookie']) {
            curl_setopt(self::$config['Curl'], CURLOPT_COOKIE, self::$request['Cookie']);
        }

        //设置Referer
        if (self::$request['Referer']) {
            curl_setopt(self::$config['Curl'], CURLOPT_REFERER, self::$request['Referer']);
        }
        //赋值结果
        self::$response['Content'] = curl_exec(self::$config['Curl']);
        self::$response['Status'] = curl_getinfo(self::$config['Curl'], CURLINFO_HTTP_CODE);
        self::$response['Error'] = curl_error(self::$config['Curl']);

        //关闭CURL会话
        curl_close(self::$config['Curl']);
    }


    public static function setGetRequestInfo($url, $param, $port)
    {
        self::$request['Url'] = $url;
        self::$request['Prot'] = $port;
        self::$request['Param'] = $param;
        self::$request['Method'] = 'GET';
    }

    public static function setPostRequestInfo($url, $body, $port)
    {
        self::$request['Url'] = $url;
        self::$request['Prot'] = $port;
        self::$request['Body'] = $body;
        self::$request['Method'] = 'POST';
    }
    public static function setPutRequestInfo($url, $body, $port)
    {
        self::$request['Url'] = $url;
        self::$request['Prot'] = $port;
        self::$request['Body'] = $body;
        self::$request['Method'] = 'PUT';
    }
    public static function setPatchRequestInfo($url, $body, $port)
    {
        self::$request['Url'] = $url;
        self::$request['Prot'] = $port;
        self::$request['Body'] = $body;
        self::$request['Method'] = 'PATCH';
    }
    public static function setDeleteRequestInfo($url, $body, $port)
    {
        self::$request['Url'] = $url;
        self::$request['Prot'] = $port;
        self::$request['Body'] = $body;
        self::$request['Method'] = 'DELETE';
    }

    /**
     * 设置Body类型
     * @param string $mode 类型[x-www-form-urlencoded | ]
     * @return void
     */
    public static function setBodyType($mode)
    {
        self::$request['BodyType'] = $mode;
    }

    /**
     * 设置Header头
     * @param array $headers
     * @return void
     */
    public static function setHeaders($headers, $isOverlay = false)
    {
        if ($isOverlay) {
            self::$request['Headers'] = $headers;
        } else {
            self::$request['Headers'] = array_merge(self::$request['Headers'], $headers);
        }
    }

    /**
     * 设置Cookie值
     * @param string $cookie
     * @return void
     */
    public static function setCookie($cookie)
    {
        self::$request['Cookie'] = self::$request['Cookie'] .= $cookie;
    }

    /**
     * 设置Cookie值
     * @param string $referer
     * @return void
     */
    public static function setReferer($referer)
    {
        self::$request['Referer'] = self::$request['Referer'] .= $referer;
    }


    /**
     * 设置SSL信息
     * @param boolean $isOpen 是否开启SSL
     * @param [type] $cert 携带证书
     * @param [type] $key 携带密钥
     * @return void
     */
    public static function setSSL($isOpen = true, $cert = null, $key = null)
    {
        self::$request['SSL'] = array(
            'IsOpen' => $isOpen,
            'Cert' => $cert,
            'Key' => $key
        );
    }

    /**
     * 获取响应状态
     * @return void
     */
    public static function getHttpState()
    {
        return self::$response['Status'];
    }

    /**
     * 获取响应Cookie
     * @return string
     */
    public static function getCookie()
    {
        preg_match('/^Set-Cookie: (.*?);/m', self::$response['Content'], $value);
        $cookie = parse_url($value[1]);
        return $cookie['path'];
    }

    /**
     * 获取响应Json
     * @return string
     */
    public static function getJson()
    {
        return strstr(self::$response['Content'], '{');
    }

    /**
     * 获取响应Xml
     * @return string
     */
    public static function getXml()
    {
        return strstr(self::$response['Content'], '<xml>');
    }

    /**
     * 获取响应结果
     * @return void
     */
    public static function getResult()
    {
        return self::$response['Content'];
    }

    /**
     * 获取响应错误
     * @return void
     */
    public static function getError()
    {
        return self::$response['Error'];
    }
}
